/**
 *  @file: SleepTask.cpp
 *  @author: nwz
 *  @brief: 
 *  @date: 2024年8月5日
 * 
 */

#define TAG "sleeptask"
#include <code/task/SleepTask.h>

namespace task {

void configAndEnterSleepMode(void) {
	// disable ioretention
	HAL_PWREx_DisableStandbyIORetention();
	// config wakeup pin a2
	__HAL_RCC_GPIOA_CLK_ENABLE();
	// enable wake pin
	HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN2_LOW);
	__HAL_PWR_CLEAR_FLAG(PWR_WAKEUP_FLAG2);
	// enter standby mode
	HAL_PWR_EnterSTANDBYMode();
}

SleepTask::SleepTask(bsp::BKPSRam bkram) :
		bkram { bkram } {
	// TODO Auto-generated constructor stub

}

SleepTask::~SleepTask() {
	// TODO Auto-generated destructor stub
}

int SleepTask::init() {
	sem = xSemaphoreCreateBinary();
	ASSERT(sem);
	return 0;
}

void SleepTask::enterSleep() {
	xSemaphoreGive(sem);
}

void SleepTask::run_() {
	while (true) {
		ASSERT(xSemaphoreTake(sem, portMAX_DELAY) == pdTRUE);
		vTaskSuspendAll();
		bkram.setBootFlag(0x01);
		configAndEnterSleepMode();
	}
}

void SleepTask::CheckOk(bsp::BKPSRam ram) {
	auto start = NOW();
	if (ram.getBootFlag() == 0x01) {
		while (NOW() - start <= KEY_LONG_CLICK_TIME) {
			if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_2) == GPIO_PIN_RESET) {
				DELAY(50);
			} else {
				configAndEnterSleepMode();
			}
		}
		ram.setBootFlag(0);
	}
}

} /* namespace task */
